package org.example.mall.admin.service.manage;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.example.mall.admin.configuration.file.BaseCallback;
import org.example.mall.admin.configuration.file.OssProperties;
import org.example.mall.admin.configuration.file.OssTemplate;
import org.example.mall.admin.configuration.file.UrlsCallback;
import org.example.mall.admin.model.entity.manage.SysFile;
import org.example.mall.admin.util.R;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * <p>
 * 文件管理表 服务类
 * </p>
 *
 * @author hzq
 * @since 2022-01-04
 */
public interface SysFileService extends IService<SysFile> {

    /**
     * @return oss配置
     */
    OssProperties ossProperties();

    /**
     * @return 文件服务模板
     */
    OssTemplate minioTemplate();

    /**
     * @return 线程池任务执行器
     */
    ThreadPoolTaskExecutor applicationTaskExecutor();

    /**
     * 分页查询文件列表
     *
     * @param page    分页参数
     * @param sysFile 查询参数
     * @return 文件列表
     */
    IPage<SysFile> getPage(Page page, SysFile sysFile);

    /**
     * 移动素材分类
     *
     * @param treeId  分类id
     * @param fileIds 素材列表
     */
    Boolean moveMaterialFile(Integer treeId, String fileIds);

    /**
     * 上传文件
     */
    R<Map<String, String>> uploadFile(String bucketName, MultipartFile file, Integer treeId);

    /**
     * 上传网络文件
     */
    String uploadNetFile(String bucketName, String netUrl, String fileName);

    /**
     * 提取桶名称
     *
     * @param bucketName 桶
     */
    String extractBucketName(String bucketName);

    /**
     * @param originFileNme 原名称
     * @param md5Hex        文件唯一值
     * @return 文件路径
     */
    String extractFileName(String originFileNme, String md5Hex);

    /**
     * 读取文件
     *
     * @param bucket   桶名称
     * @param fileName 文件名称
     * @param response 输出流
     */
    void getFile(String bucket, String fileName, HttpServletResponse response);

    /**
     * 删除文件
     *
     * @param id 文件id
     */
    Boolean deleteFile(Long id);

    /**
     * 查询系统中是否存在该文件
     * 通过md5Hex判断
     *
     * @param md5Hex 文件唯一编码
     * @return 文件信息
     */
    SysFile getSysFile(String md5Hex);

    /**
     * 引用文件
     *
     * @param fileName 文件名称
     */
    void linkFile(String fileName);

    /**
     * 异步引用文件
     *
     * @param target 对象
     */
    void asyncLinkFile(Object target);

    /**
     * 修改引用文件
     *
     * @param original 对象
     * @param target   对象
     */
    void asyncEditLinkFile(Object original, Object target);

    /**
     * 解除引用
     *
     * @param target 对象
     */
    void asyncUnLinkFile(Object target);

    /**
     * 解除引用
     *
     * @param fileName 文件名称
     */
    void unLinkFile(String fileName);

    /**
     * 解除引用
     *
     * @param urls 访问地址列表 逗号分割
     */
    void unLinkFileByUrls(String urls);

    /**
     * 替换网络附件地址
     *
     * @param text 富文本
     * @return 替换过网络地址的富文本
     */
    BaseCallback replaceNetBaseCallback(String text);

    /**
     * 替换网络附件地址
     * 1、返回替换过网络地址的富文本
     * 2、返回富文本中的本系统中地址列表以","分割
     *
     * @param text 富文本
     * @return [0] 替换过网络地址的富文本 [1] /manage/sysFile?bucket=tmp&fileName=1.jpg,/manage/sysFile?bucket=tmp&fileName=2.jpg
     */
    UrlsCallback replaceNetUrlsCallback(String text);

    /**
     * @param fileName 文件名
     * @return 文件信息
     */
    SysFile getByFileName(String fileName);

    /**
     * 保存文件记录
     *
     * @param bucketName     桶
     * @param originFileName 原名称
     * @param fileName       文件路径
     * @param fileSize       文件大小
     * @param md5Hex         文件唯一
     * @param netUrl         原图片网络地址
     * @param contentType    文件类型
     * @param treeId         分类id
     */
    SysFile saveSysFileLog(String bucketName, String originFileName, String fileName, long fileSize,
                           String md5Hex, String netUrl, String contentType, Integer treeId);
}
